/*
 * Created on 2006-01-14
 */
package dk.aiszone.lang.autosource.generatorobjects;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import dk.aiszone.lang.autosource.generatorobjects.interfaces.GeneratorObject;

/**
 * Container of JavaDoc.<br>
 * The <code>JavaDoc</code> class can contain the following information:
 * <ul>
 * <li>params
 * <li>author
 * <li>see
 * <li>since
 * <li>version
 * </ul>
 * 
 * Linebreaks in the supplied text is converted to the &lt;br&gt; tag.
 * 
 * @author <a href="mailto:ais@mail.dk">Ais</a>
 * @since 1.0
 * @version 1.0
 */
public class JavaDoc extends GeneratorObject {

    private String _return;
    private Map<String, String> _throws;
    private String author;
    private String description;
    private MethodDeclaration parentMethod;
    private Map<String, String> sees;
    private String since;
    private String version;

    /**
     * Default constructor for the <code>JavaDoc</code> class.
     */
    public JavaDoc() {
        sees = new LinkedHashMap<String, String>();
        _throws = new LinkedHashMap<String, String>();
    }

    /**
     * The <code>AddParam</code> method has been replaced by the {@link Argument#setJavaDoc(String)} method.
     * 
     * @param name
     *            Not used
     * @param description
     *            Not used
     */
    @Deprecated
    public void addParam(String name, String description) {
    // Do nothing
    }

    /**
     * Add a <code>see</code> attribute to the <code>JavaDoc</code> class.
     * 
     * @param reference
     *            The see reference
     * @param description
     *            <b>Optionally:</b> Description of the reference
     */
    public void addSee(String reference, String description) {
        sees.put(reference, description);
    }

    /**
     * Add a <code>throws</code> attribute to the <code>JavaDoc</code> class.
     * 
     * @param exception
     *            The exception being thrown
     * @param description
     *            <b>Optionally:</b> Description of the exception
     */
    public void addThrows(String exception, String description) {
        _throws.put(exception, description);
    }

    /**
     * Retrieve the author
     * 
     * @return The author
     */
    public String getAuthor() {
        return author;
    }

    /**
     * Retrieve the description contained in the <code>JavaDoc</code>
     * 
     * @return The description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Retrieve the parameters contained in the <code>JavaDoc</code>.
     * 
     * @return The parameters
     */
    public Map<String, String> getParameters() {
        if (parentMethod != null) {
            Map<String, String> tmp = new LinkedHashMap<String, String>();

            for (Iterator<Argument> iterator = parentMethod.getArguments().iterator(); iterator.hasNext();) {
                Argument argument = iterator.next();
                tmp.put(argument.getName(), argument.getJavaDoc());
            }

            return Collections.unmodifiableMap(tmp);
        }
        return Collections.emptyMap();
    }

    /**
     * Retrieve the <code>return</code> attribute
     * 
     * @return Description of the returned value
     */
    public String getReturn() {
        return _return;
    }

    /**
     * Retrieve the <code>see</code> attributes of the <code>JavaDoc</code>.
     * 
     * @return The see referemces
     */
    public Map<String, String> getSees() {
        return sees;
    }

    /**
     * Retrieve the since attribute
     * 
     * @return The since attribute
     */
    public Object getSince() {
        return since;
    }

    /**
     * Retrieve the <code>throws</code> attributes of the <code>JavaDoc</code>.
     * 
     * @return The exception being thrown
     */
    public Map<String, String> getThrows() {
        return _throws;
    }

    /**
     * Retrieve the version
     * 
     * @return The version
     */
    public String getVersion() {
        return version;
    }

    /**
     * Retrieve whether the <code>JavaDoc</code> class contains data.
     * 
     * @return <code>true</code> if empty - otherwise <code>false</code>.
     */
    public boolean isEmpty() {
        if (_return != null) {
            return false;
        }
        if (!_throws.isEmpty()) {
            return false;
        }
        if (author != null) {
            return false;
        }
        if (description != null) {
            return false;
        }
        if (!sees.isEmpty()) {
            return false;
        }
        if (since != null) {
            return false;
        }
        if (version != null) {
            return false;
        }
        return true;
    }

    /**
     * Set the <code>author</code> attribute
     * 
     * @param author
     *            The author of the file / method
     */
    public void setAuthor(String author) {
        this.author = author;
    }

    /**
     * Set the common description displayed in the start of the JavaDoc.
     * 
     * @param description
     *            The text to display in the JavaDoc.
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Set the <code>return</code> attribute
     * 
     * @param _return
     *            Description of the returned value
     */
    public void setReturn(String _return) {
        this._return = _return;
    }

    /**
     * Set the <code>since</code> attribute
     * 
     * @param since
     *            The since information
     */
    public void setSince(String since) {
        this.since = since;
    }

    /**
     * Set the <code>version</code> attribute
     * 
     * @param version
     *            The version info
     */
    public void setVersion(String version) {
        this.version = version;
    }

    /* pp */void setParentMethod(MethodDeclaration method) {
        if (this.parentMethod != null) {
            throw new IllegalStateException("JavaDoc already has a parent");
        }
        this.parentMethod = method;
    }
}